home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
409_01
/
svgac.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-21
|
26KB
|
733 lines
/****************************************************************************
*
* SuperVGA Test Library
*
* Copyright (C) 1993 SciTech Software
* All rights reserved.
*
* Filename: $RCSfile: svgac.c $
* Version: $Revision: 1.3 $
*
* Language: ANSI C
* Environment: IBM PC (MSDOS)
*
* Description: Simple library to collect together the functions in the
* SuperVGA test library for use in other C programs. The
* support is reasonably low level, so you can do what you
* want. The set of routines in this source file are general
* SuperVGA routines and are independant of the video mode
* selected.
*
* MUST be compiled in the large model.
*
* $Id: svgac.c 1.3 1993/10/22 08:58:40 kjb release $
*
****************************************************************************/
#include <string.h>
#include <dos.h>
#include <stdlib.h>
#include "svga.h"
#include "vesavbe.h"
/*---------------------------- Global Variables ---------------------------*/
#define MAXMODES 50 /* Maximum modes available in list */
int maxx,maxy,memory;
long maxcolor,defcolor;
int maxpage,bytesperline;
uchar redMask,greenMask,blueMask;
int redPos,redAdjust;
int greenPos,greenAdjust;
int bluePos,blueAdjust;
bool twobanks = false,extendedflipping = false,widedac = false;
short modeList[MAXMODES];
char OEMString[80];
int oldMode; /* Old video mode number */
bool old50Lines; /* Was old mode 80x50? */
int curBank; /* Current read/write bank */
int bankAdjust; /* Bank granularity adjust factor */
long pagesize; /* Page size for current mode */
void *bankSwitch; /* Pointer to bank switch routine */
void *writeBank; /* Relocated write bank routine */
void *readBank; /* Relocated read bank routine */
void *pageFlip; /* Relocated page flip routine */
void (*putPixel)(int x,int y,long color);
void (*clear)(void);
/*----------------------------- Implementation ----------------------------*/
/* Declare all video mode dependent routines */
void _putPixel16(int x,int y,long color);
void _putPixel256(int x,int y,long color);
void _putPixel32k(int x,int y,long color);
void _putPixel64k(int x,int y,long color);
void _putPixel16m(int x,int y,long color);
void _clear16(void);
void _clear256(void);
void _clear32k(void);
void _clear64k(void);
void _clear16m(void);
PRIVATE bool checkVESAPageFlip(void)
/****************************************************************************
*
* Function: checkVESAPageFlip
* Returns: True if VBE supports page flipping.
*
* Description: Determines if the VESA VBE supports extended page
* flipping or not. Assume a suitable video mode has already
* been initialised.
*
****************************************************************************/
{
union REGS regs;
regs.x.ax = 0x4F07; /* Set display start service */
regs.x.bx = 0; /* BH := 0, BL := 0 (set display start) */
regs.x.cx = 0; /* Leftmost pixel in line */
regs.x.dx = 0; /* First displayed scanline */
int86(0x10,®s,®s);
if (regs.x.ax != 0x004F)
return false; /* Function failed, not page flip */
regs.x.ax = 0x4F07; /* Get display start service */
regs.x.bx = 1; /* BH := 0, BL := 1 (get display start) */
int86(0x10,®s,®s);
if (regs.x.ax != 0x004F)
return false; /* Function failed, not page flip */
if (regs.h.bh != 0)
return false;
if (regs.x.cx != 0)
return false;
if (regs.x.dx != 0)
return false;
return true;
}
bool checkWideDAC(void)
/****************************************************************************
*
* Function: checkWideDAC
* Returns: True if 8 bit wide DAC is supported.
*
* Description: Tests to see if the VBE BIOS supports an 8 bit wide
* DAC. This assumes the video card is in an appropriate
* video mode before being called.
*
****************************************************************************/
{
union REGS regs;
short bits;
regs.x.ax = 0x4F08; /* Set DAC service */
regs.x.bx = 0x0800; /* BH := 8, BL := 0 (set DAC width) */
int86(0x10,®s,®s);
if (regs.x.ax != 0x004F)
return false; /* Function failed, no wide dac */
if (regs.h.bh == 6)
return false;
regs.x.ax = 0x4F08;
regs.x.bx = 0x0001; /* Get DAC width (should now be 8) */
int86(0x10,®s,®s);
if (regs.x.ax != 0x004F)
return false;
bits = regs.h.bh;
regs.x.ax = 0x4F08;
regs.x.bx = 0x0600;
int86(0x10,®s,®s); /* Restore to 6 bit DAC */
if (regs.x.ax != 0x004F)
return false;
return (bits == 8);
}
PUBLIC int initSuperVGA(void)
/****************************************************************************
*
* Function: initSuperVGA
* Returns: VBE version number for the SuperVGA (0 if no SuperVGA).
*
* Description: Detects if a VESA VBE compliant SuperVGA is out there, and
* initialises the library if one is. The VBE version number
* is specified with the major version number in the high
* byte and the minor version number in the low byte. So
* version 1.2 is the number 0x102.
*
****************************************************************************/
{
VgaInfoBlock vgaInfo;
ModeInfoBlock modeInfo;
union REGS regs;
struct SREGS sregs;
short *p,i;
sregs.es = SEG(&vgaInfo);
regs.x.di = OFF(&vgaInfo);
regs.x.ax = 0x4F00;
int86x(0x10,®s,®s,&sregs); /* Get SuperVGA information */
if (regs.x.ax != 0x004F)
return false;
if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0)
return false;
/* Copy relavent information from the mode block into our globals.
* Note that the video mode list _may_ be built in the information
* block that we have passed, so we _must_ copy this from here
* into our our storage if we want to continue to use it. Note
* that we filter out the mode 0x6A, which some BIOSes include as
* well as the 0x102 mode for 800x600x16.
*/
for (i = 0,p = vgaInfo.VideoModePtr; *p != -1; p++,i++) {
if (*p != 0x6A)
modeList[i] = *p;
}
modeList[i] = -1;
memory = vgaInfo.TotalMemory * 64;
strcpy(OEMString,vgaInfo.OEMStringPtr);
/* Determine if the board supports separate read/write banks and
* extended page flipping. Some VESA VBE's require the card to be
* in a graphics mode for these tests to work, so we find a suitable
* mode and use that.
*/
for (p = modeList; *p != -1; p++) {
sregs.es = SEG(&modeInfo);
regs.x.di = OFF(&modeInfo);
regs.x.ax = 0x4F01;
regs.x.cx = *p;
int86x(0x10,®s,®s,&sregs); /* Get SuperVGA mode info */
if (regs.x.ax == 0x004F &&
(modeInfo.MemoryModel == 3 || modeInfo.MemoryModel == 4)) {
modeInfo.WinBAttributes &= 0x7;
twobanks = (modeInfo.WinBAttributes == 0x3);
setSuperVGAMode(*p);
extendedflipping = checkVESAPageFlip();
widedac = checkWideDAC();
restoreMode();
break;
}
}
return vgaInfo.VESAVersion;
}
PRIVATE void computePageInfo(ModeInfoBlock *modeInfo,int *maxpage,
long *pages